package com.acheli.utils.physics;



import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.VoxelShape;

import java.util.ArrayList;
import java.util.List;


public class PhysicsEngine {
    private final List<PhysicsObject> objList = new ArrayList<>();
    public void registryObj (PhysicsObject physicsObject) {
        objList.add(physicsObject);
    }

    void physicsEngineTick (float tickDelta) {
        for (PhysicsObject physicsObject : objList) {
            physicsObject.physicsObjTick(tickDelta);
        }
    }

    public static Vec3 every(double d) {
        return new Vec3(d, d, d);
    }

    public static float getDeltaTime(float tickDelta) {
        // 动态时间步长 (基于渲染帧间隔)
        return tickDelta * 0.05f; // 将 tickDelta 转换为秒
    }

    // 物理计算方法
    public static Vec3 getAcceleration(Vec3 force, double mass) { //加速度
        //F = ma, a = F/m, a = F * 1/m
        return force.multiply(every(1 / mass));
    }

    public static Vec3 getForce(double mass, Vec3 acceleration) { //加速度
        //F = ma
        return acceleration.multiply(every(mass));
    }

    public static Vec3 getMomentum(double mass, Vec3 speed) { //根据质量与速度求动量
        return new Vec3(speed.x() * mass, speed.y() * mass, speed.z() * mass);
    }
    public static Vec3 getSpeedFromMomentum (double mass, Vec3 momentum) { //根据质量与动量求速度
        if (mass == 0) {
            return Vec3.ZERO;
        }
        return new Vec3(momentum.x() / mass, momentum.y() / mass, momentum.z() / mass);
    }

    public static boolean isEntityInsideBlock(Entity entity) {
        Level world = entity.level();
        AABB entityAABB = entity.getBoundingBox();

        // 确定检测范围，这里以实体位置为中心扩展2个方块
        int minX = (int) Math.floor(entityAABB.minX - 1);
        int minY = (int) Math.floor(entityAABB.minY - 1);
        int minZ = (int) Math.floor(entityAABB.minZ - 1);
        int maxX = (int) Math.ceil(entityAABB.maxX + 1);
        int maxY = (int) Math.ceil(entityAABB.maxY + 1);
        int maxZ = (int) Math.ceil(entityAABB.maxZ + 1);

        // 遍历范围内的每个方块
        for (int x = minX; x <= maxX; x++) {
            for (int y = minY; y <= maxY; y++) {
                for (int z = minZ; z <= maxZ; z++) {
                    BlockPos pos = new BlockPos(x, y, z);
                    BlockState state = world.getBlockState(pos);

                    // 获取方块的碰撞形状
                    VoxelShape shape = state.getCollisionShape(world, pos);
                    if (shape.isEmpty()) continue; // 忽略无碰撞箱的方块

                    // 将VoxelShape转换为世界坐标的AABB并检测交集
                    for (AABB blockAABB : shape.toAabbs()) {
                        AABB translatedAABB = blockAABB.move(pos.getX(), pos.getY(), pos.getZ());
                        if (entityAABB.intersects(translatedAABB)) {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }

}